
#include <libcoco.h>
#include "s_task.h"


#define CROUT_MALLOC(size)	  __builtin_malloc(size)
#define CROUT_FREE(ptr, size)   __builtin_free(ptr)

// /* Create a new task */
// typedef void(*s_task_fn_t)(__future__, void *arg);
// void s_task_create(void *stack, size_t stack_size, s_task_fn_t entry, void *arg);

// /* Wait a task to exit */
// int s_task_join(__future__, void *stack);

// /* Kill a task */
// void s_task_kill(void *stack);

// /* Sleep in ticks */
// int s_task_sleep_ticks(__future__, my_clock_t ticks);

// /* Sleep in milliseconds */
// int s_task_msleep(__future__, uint32_t msec);

// /* Sleep in seconds */
// int s_task_sleep(__future__, uint32_t sec);

// /* Yield current task */
// void s_task_yield(__future__);

// /* Cancel task waiting and make it running */
// void s_task_cancel_wait(void* stack);

// /* Get free stack size (for debug) */
// size_t s_task_get_stack_free_size(void);

typedef struct crout_int{
	// word_t   stk_size;
	void *(*routine)(void*);
	void *arg;
	void *stk;
	size_t stk_size;
}crout_int_t;

static void async_worker(__future__, void *ud){
	crout_int_t *cr = (crout_int_t *)ud;
	// coroutine_yield(cr->S);
	s_task_yield(__await__);
	void *ret = cr->routine(cr->arg);
	// cr->ret = ret;
}

/* 全局初始化 */
static __attribute__((constructor)) void s_task_sysinit(){
	s_task_init_system();
}

int 	crout_create( crout_t **pco,const crout_attr_t *attr,void *(*routine)(void*),void *arg){
	void *p = CROUT_MALLOC(sizeof(crout_int_t));
	if (!p) return -1;
	crout_int_t * cr = (crout_int_t *)p;
	// cr->stk_size = attr->stack_size;
	// cr->routine = routine;
	// cr->arg = arg;
	// cr->S = coroutine_open();
	// cr->coid = coroutine_new(cr->S, async_worker, cr);
	// coroutine_resume(cr->S, cr->coid);
	cr->stk = CROUT_MALLOC(attr->stack_size);
	if (!cr->stk) return -1;
	cr->stk_size = (size_t)attr->stack_size;
	s_task_create(cr->stk, cr->stk_size, async_worker, cr);
	__future__ = 0;
	s_task_yield(__await__);
	*pco = (crout_t *)cr;

	return 0;
}

void	crout_resume( crout_t *co){
	crout_int_t *cr = (crout_int_t *)co;
	// coroutine_resume(cr->S, cr->coid);
}


void	crout_yield( crout_t *co ){
	crout_int_t *cr = (crout_int_t *)co;
	// coroutine_yield(cr->S);
}

void	crout_release( crout_t *co ){
	crout_int_t *cr = (crout_int_t *)co;
	// coroutine_close(cr->S);
	CROUT_FREE(cr, sizeof(crout_int_t));
}

void	crout_reset(crout_t * co){
	crout_int_t *cr = (crout_int_t *)co;

}
